package com.guchenbo.example.httpclient;

import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.config.CookieSpecs;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.DefaultProxyRoutePlanner;
import org.apache.http.ssl.SSLContexts;
import org.apache.http.ssl.TrustStrategy;

import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

/**
 * @Author gucb
 * @Date 2017/9/1.
 */
public class MyHttpClient extends BasicHttpClient {


    public int CONNECT_TIMEOUT = 6; //unit: second
    public int READ_TIMEOUT = 30; //unit: second
    public int CONNECT_REQUEST_TIMEOUT = 6; //unit: second

    protected CloseableHttpClient client;

    public MyHttpClient() {
        initClient();
    }

    protected void initClient() {
        try {
            RequestConfig requestConfig = RequestConfig.custom().setCircularRedirectsAllowed(false)
                            .setSocketTimeout(READ_TIMEOUT * 1000).setConnectTimeout(CONNECT_TIMEOUT * 1000)
                            .setConnectionRequestTimeout(CONNECT_REQUEST_TIMEOUT * 1000)
                            .setCookieSpec(CookieSpecs.IGNORE_COOKIES).setMaxRedirects(0).build();

            HttpClientBuilder builder = HttpClients.custom();
            //add proxy
            HttpHost proxy = new HttpHost("192.168.6.132", 8888);
            DefaultProxyRoutePlanner routePlanner = new DefaultProxyRoutePlanner(proxy);
            builder.setRoutePlanner(routePlanner);
            //add ssl
            SSLContext sslContext = SSLContexts.custom().useProtocol("TLS")

                            .loadTrustMaterial((chain, authType) -> true)
                            .build();
            SSLConnectionSocketFactory sslConnectionSocketFactory = new SSLConnectionSocketFactory(sslContext
//                            ,
//                            (s, sslSession) -> false
            );
            builder.setSSLSocketFactory(sslConnectionSocketFactory);
            builder.setDefaultRequestConfig(requestConfig);
//            builder.setDefaultCredentialsProvider(new CustomCredentialProvider("chenbo.gu", "Lvlingai@168"));
            client = builder.build();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    class MyTrustStrategy implements TrustStrategy {

        @Override
        public boolean isTrusted(X509Certificate[] chain, String authType) throws CertificateException {
            return true;
        }
    }

    class MyHostnameVerifier implements HostnameVerifier {

        @Override
        public boolean verify(String s, SSLSession sslSession) {
            return true;
        }
    }

    public void executeAndPrint(String url) {
        executeAndPrint(url, Method.get);
    }

    public void executeAndPrint(String url, Method method) {
        HttpRequestBase httpRequest = null;
        if (Method.post == method) {
            httpRequest = new HttpPost(url);
        } else {
            httpRequest = new HttpGet(url);
        }

        execute(httpRequest, callBack);
    }

    public void executeAndPrint(HttpUriRequest httpRequest) {
        execute(httpRequest, callBack);
    }

    public void execute(HttpUriRequest httpRequest, HttpResponseCallBack action) {
        doExecute(httpRequest, action);
    }

    protected void doExecute(HttpUriRequest httpRequest, HttpResponseCallBack action) {
        try {
            HttpResponse httpResponse = client.execute(httpRequest);
            action.doAction(httpResponse);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
